package com.intercom;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;

import android.util.Log;
import android.widget.Toast;
import android.app.Application;

public class Core extends Application {
	
	private String DATA_FILE_PATH;
	public static final String MSG_TAG = "TETHER -> Core";
	
	
    
    @Override
    public void onCreate() {
		Log.d(MSG_TAG, "Calling onCreate()");
		//create CoreTask
		this.setPath(this.getApplicationContext().getFilesDir().getParent());
		Log.d(MSG_TAG, "Current directory is "+this.getApplicationContext().getFilesDir().getParent());
		checkDirs();
    	installFiles();
    }
    
	@Override
	public void onTerminate() {
		Log.d(MSG_TAG, "Calling onTerminate()");
//    	// Stopping Tether
//		this.stopTether();
//		// Remove all notifications
//		this.notificationManager.cancelAll();
	}
	
	 
	
	public void setPath(String path) {
		Core.this.DATA_FILE_PATH = path; //this.getApplicationContext().getFilesDir().getParent()
	}
	
    private String copyFile(String filename, String permission, int ressource) {
    	String result = this.copyFile(filename, ressource);
    	if (result != null) {
    		return result;
    	}
    	if (this.chmod(filename, permission) != true) {
    		result = "Can't change file-permission for '"+filename+"'!";
    	}
    	return result;
    }
    
    public boolean chmod(String file, String mode) {
    	if (NativeTask.runCommand("chmod "+ mode + " " + file) == 0) {
    		return true;
    	}
    	return false;
    }
    
    public boolean start() {
    	return this.runRootCommand(this.DATA_FILE_PATH+"/bin/tether start 1");
    }
    
    public boolean stop() {
    	return this.runRootCommand(this.DATA_FILE_PATH+"/bin/tether stop 1");
    }
    
    public boolean runRootCommand(String command) {
		Log.d(MSG_TAG, "Root-Command ==> su -c \""+command+"\"");
		int returncode = NativeTask.runCommand("su -c \""+command+"\"");
    	if (returncode == 0) {
			return true;
		}
    	Log.d(MSG_TAG, "Root-Command error, return code: " + returncode);
		return false;
    }
    
    private String copyFile(String filename, int ressource) {
    	File outFile = new File(filename);
    	Log.d(MSG_TAG, "Copying file '"+filename+"' ..");
    	InputStream is = this.getResources().openRawResource(ressource);
    	byte buf[] = new byte[1024];
        int len;
        try {
        	OutputStream out = new FileOutputStream(outFile);
        	while((len = is.read(buf))>0) {
				out.write(buf,0,len);
			}
        	out.close();
        	is.close();
		} catch (IOException e) {
			return "Couldn't install file - "+filename+"!";
		}
		return null;
    }
	
	 public void installFiles() {
	    	new Thread(new Runnable(){
				public void run(){
					String message = null;
					// tether
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/tether", "0755", R.raw.tether);
			    	}
			    	// dnsmasq
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/dnsmasq", "0755", R.raw.dnsmasq);
			    	}
			    	// iptables
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/iptables", "0755", R.raw.iptables);
			    	}
			    	// ifconfig
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/ifconfig", "0755", R.raw.ifconfig);
			    	}	
			    	// iwconfig
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/iwconfig", "0755", R.raw.iwconfig);
			    	}
			    	// ultra_bcm_config
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/ultra_bcm_config", "0755", R.raw.ultra_bcm_config);
			    	}
			    	//pand
			    	if (message == null) {
				    	message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/pand", "0755", R.raw.pand);
			    	}
			    	// blue-up.sh
					if (message == null) {
						message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/blue-up.sh", "0755", R.raw.blue_up_sh);
					}
					// blue-down.sh
					if (message == null) {
						message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/blue-down.sh", "0755", R.raw.blue_down_sh);
					}		
					
					/**
					 * Installing fix-scripts if needed
					 */
//					if (Configuration.enableFixPersist()) {	
//						// fixpersist.sh
//						if (message == null) {
//							message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/fixpersist.sh", "0755", R.raw.fixpersist_sh);
//						}				
//					}
//					if (Configuration.enableFixRoute()) {
//						// fixroute.sh
//						if (message == null) {
//							message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/bin/fixroute.sh", "0755", R.raw.fixroute_sh);
//						}
//					}
					
			    	// dnsmasq.conf
					if (message == null) {
						message = Core.this.copyFile(Core.this.DATA_FILE_PATH+"/conf/dnsmasq.conf", "0644", R.raw.dnsmasq_conf);
						Core.this.updateDnsmasqFilepath(); 
					}
			    	// tiwlan.ini
					if (message == null) {
						Core.this.copyFile(Core.this.DATA_FILE_PATH+"/conf/tiwlan.ini", "0644", R.raw.tiwlan_ini);
					}
					// edify script
					if (message == null) {
						Core.this.copyFile(Core.this.DATA_FILE_PATH+"/conf/tether.edify", "0644", R.raw.tether_edify);
					}
					// tether.cfg
					if (message == null) {
						Core.this.copyFile(Core.this.DATA_FILE_PATH+"/conf/tether.conf", "0644", R.raw.tether_conf);
					}
					
					// wpa_supplicant drops privileges, we need to make files readable.
					Core.this.chmod(Core.this.DATA_FILE_PATH+"/conf/", "0755");

//					if (message == null) {
//				    	message = getString(R.string.global_application_installed);
//					}
					
					// Sending message
//					Message msg = new Message();
//					msg.obj = message;
//					Core.this.displayMessageHandler.sendMessage(msg);
				}
			}).start();
	    }
	    public synchronized void updateDnsmasqFilepath() {
	    	String dnsmasqConf = this.DATA_FILE_PATH+"/conf/dnsmasq.conf";
	    	String newDnsmasq = new String();
	    	boolean writeconfig = false;
	    	
	    	ArrayList<String> lines = readLinesFromFile(dnsmasqConf);
	    	
	    	for (String line : lines) {
	    		if (line.contains("dhcp-leasefile=") && !line.contains(Core.this.DATA_FILE_PATH)){
	    			line = "dhcp-leasefile="+Core.this.DATA_FILE_PATH+"/var/dnsmasq.leases";
	    			writeconfig = true;
	    		}
	    		else if (line.contains("pid-file=") && !line.contains(Core.this.DATA_FILE_PATH)){
	    			line = "pid-file="+Core.this.DATA_FILE_PATH+"/var/dnsmasq.pid";
	    			writeconfig = true;
	    		}
	    		newDnsmasq += line+"\n";
	    	}

	    	if (writeconfig == true)
	    		writeLinesToFile(dnsmasqConf, newDnsmasq);
	    }
	    public ArrayList<String> readLinesFromFile(String filename) {
	    	String line = null;
	    	BufferedReader br = null;
	    	InputStream ins = null;
	    	ArrayList<String> lines = new ArrayList<String>();
	    	File file = new File(filename);
	    	if (file.canRead() == false)
	    		return lines;
	    	try {
	    		ins = new FileInputStream(file);
	    		br = new BufferedReader(new InputStreamReader(ins), 8192);
	    		while((line = br.readLine())!=null) {
	    			lines.add(line.trim());
	    		}
	    	} catch (Exception e) {
	    		Log.d(MSG_TAG, "Unexpected error - Here is what I know: "+e.getMessage());
	    	}
	    	finally {
	    		try {
	    			ins.close();
	    			br.close();
	    		} catch (Exception e) {
	    			// Nothing.
	    		}
	    	}
	    	return lines;
	    }
	    
	    public boolean writeLinesToFile(String filename, String lines) {
			OutputStream out = null;
			boolean returnStatus = false;
			Log.d(MSG_TAG, "Writing " + lines.length() + " bytes to file: " + filename);
			try {
				out = new FileOutputStream(filename);
	        	out.write(lines.getBytes());
	        	out.flush();
			} catch (Exception e) {
				Log.d(MSG_TAG, "Unexpected error - Here is what I know: "+e.getMessage());
			}
			finally {
	        	try {
	        		if (out != null)
	        			out.close();
	        		returnStatus = true;
				} catch (IOException e) {
					returnStatus = false;
				}
			}
			return returnStatus;
	    }
	    
	    public void HelloWorld(String str) {
	    	Log.d(MSG_TAG, "Writing " + str);
	    }
	    
	    private void checkDirs() {
	    	File dir = new File(this.DATA_FILE_PATH);
	    	if (dir.exists() == false) {
	    			this.displayToastMessage("Application data-dir does not exist!");
	    	}
	    	else {
	    		//String[] dirs = { "/bin", "/var", "/conf", "/library" };
	    		String[] dirs = { "/bin", "/var", "/conf" };
	    		for (String dirname : dirs) {
	    			dir = new File(this.DATA_FILE_PATH + dirname);
	    	    	if (dir.exists() == false) {
	    	    		if (!dir.mkdir()) {
	    	    			this.displayToastMessage("Couldn't create " + dirname + " directory!");
	    	    		}
	    	    	}
	    	    	else {
	    	    		Log.d(MSG_TAG, "Directory '"+dir.getAbsolutePath()+"' already exists!");
	    	    	}
	    		}
	    	}
	    }
		public void displayToastMessage(String message) {
			Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
		}
}
